package com.cqcvc.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.cqcvc.config.JwtToken;
import com.cqcvc.config.Result;
import com.cqcvc.entity.User;
import com.cqcvc.service.UserService;
import com.cqcvc.util.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.hutool.core.io.FileUtil.*;

@RestController
@Api(tags = "用户管理")
@RequestMapping("/user")
public class UserController {
    @Value("${upload.path}")
    String uploadPath;
    @Autowired
    private UserService userService;

    @PostMapping("/login")
    @ApiOperation(value = "用户登录")
    public String login(@RequestBody User user) {
        //判断用户名或密码是否为空
        if (user.getUsername() == null || user.getPassword() == null) {
            return JSON.toJSONString(new Result().setCode(500).setMessage("用户名和密码均不能为空！"));
        }
        Subject subject = SecurityUtils.getSubject();
        String jwt = JwtUtil.createJWT(user.getUsername(), "back", "user", 1000 * 60 * 30);
        JwtToken jwtToken = new JwtToken(jwt, user.getPassword());
        try {
            subject.login(jwtToken);
        } catch (UnknownAccountException e) {
            return JSON.toJSONString(new Result().setCode(401).setMessage("账号不存在！"));
        } catch (IncorrectCredentialsException e) {
            return JSON.toJSONString(new Result().setCode(401).setMessage("密码错误！"));
        }
        //将获取的用户进行返回
        User backUser = userService.getUserByUsername(user.getUsername());

        //为安全起见，将password和salt置为空
        backUser.setPassword(null);
        backUser.setSalt(null);
        Map<String, Object> map = new HashMap<>();
        map.put("user", backUser);
        map.put("token", jwt);
        return JSON.toJSONString(new Result().setCode(200).setMessage("登录成功！").setData(map));
    }

    @GetMapping("/getMenuList")
    @ApiOperation("获取导航菜单")
    public String getMenuList(String username) {
        if (StringUtils.isBlank(username)) {
            return JSON.toJSONString(new Result().setCode(401).setMessage("用户未登陆!"));
        }
        List<Map<String, Object>> list = userService.getMenuList(username);
        return JSON.toJSONString(new Result().setCode(200).setData(list));
    }

    @RequiresPermissions("user:select")
    @GetMapping("/select")
    @ApiOperation(value = "查询所有用户信息")
    public String selectUser(String pageNum, String pageSize, String username, String sex) {
        Map<String, Object> map = userService.selectUser(pageNum, pageSize, username, sex);
        if ((long) map.get("total") == 0) {
            return JSON.toJSONString(new Result().setCode(200).setMessage("没有用户信息！"));
        } else {
            return JSON.toJSONString(new Result().setCode(200).setData(map));
        }
    }

    @RequiresPermissions("user:save")
    @PostMapping("/save")
    @ApiOperation("添加新用户")
    public String saveUser(@RequestBody User user){
        int i = userService.saveUser(user,user.getRoleNames());
        return JSON.toJSONString(new Result().setCode(200).setMessage("成功保存用户信息！"));
    }

    @RequiresPermissions("user:del")
    @GetMapping("/del")
    @ApiOperation("删除用户")
    public String delUser(Integer id) {
        int i = userService.delUser(id);
        if (i > 0) {
            return JSON.toJSONString(new Result().setCode(200).setMessage("成功删除用户信息！"));
        } else {
            return JSON.toJSONString(new Result().setCode(500).setMessage("删除用户信息失败！"));
        }
    }

    @RequiresPermissions("user:batchDel")
    @PostMapping("/batchDel")
    @ApiOperation("批量删除用户")
    public String batchDelUser(@RequestBody List<Integer> ids) {
        int i=userService.batchDel(ids);
        return JSON.toJSONString(new Result().setCode(200).setMessage("批量删除用户信息成功！"));
    }

    //@RequiresPermissions("user:export")
    @GetMapping("/export")
    @ApiOperation("用户数据导出")
    public void exportUser(HttpServletResponse res) throws Exception {
        List<User> list=userService.list();
        ExcelWriter writer= ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("username","账号");
        writer.addHeaderAlias("truename","姓名");
        writer.addHeaderAlias("sex","性别");
        writer.addHeaderAlias("tel","电话");
        writer.write(list,true);
        res.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName= URLEncoder.encode("用户信息","UTF-8");
        res.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
        ServletOutputStream out=res.getOutputStream();
        writer.flush(out,true);
        out.close();
        writer.close();
    }

    @PostMapping("/import")
    public Boolean importUser(MultipartFile file) throws Exception {
//        将文件上传到指定目录
//        String originalFileName=file.getOriginalFilename();
//        String type= extName(originalFileName);
//        File dest = new File(uploadPath+System.currentTimeMillis()+"."+type);
//        file.transferTo(dest);
        //将上传文件转换成对象列表
        InputStream inputStream=file.getInputStream();
        ExcelReader reader=ExcelUtil.getReader(inputStream);
        //ExcelReader reader=ExcelUtil.getReader("d:/test.xls");//可以读取一个磁盘路径
        List<User> list=reader.readAll(User.class);
        //如果数据转换成一个对象，可以一行一行的读取数据
//        List<List<Object>> lists=ExcelUtil.getReader(inputStream).read(1);
//        for(List<Object> row:lists){
//            System.out.println(row.get(0).toString());
//        }
        System.out.println(list);
        return true;
    }

    @GetMapping("/downFile")
    public void downFile(String fPath,HttpServletResponse response) throws Exception{
        //获取文件
        fPath="D:/ai/1.jpg";
        File file=new File(fPath);
        //设置输出格式
        ServletOutputStream os=response.getOutputStream();
        response.addHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fPath,"UTF-8"));
        response.setContentType("application/octet-stream");
        //读取文件的字节流
        os.write(FileUtil.readBytes(fPath));
        os.flush();
        os.close();
    }

    //测试专用
    @GetMapping("/test")
    @ApiOperation("测试用接口")
    public String test(){
        Map<String,Object> map=new HashMap<>();
        map.put("names", CollUtil.newArrayList("Java技术基础","项目管理","软件工程","人工智能基础","考研英语"));//构造成数组也可
        map.put("ages",CollUtil.newArrayList(36,29,35,49,38));
        map.put("imgs",new String[]{"https://www.cqcvc.edu.cn/Uploadfiles/Picture/2022-7-6/2022761855399009.jpg","https://www.cqcvc.edu.cn/Uploadfiles/Picture/2022-5-5/2022551547487895.jpg"});
        return JSON.toJSONString(new Result().setCode(200).setMessage("获取数据成功").setData(map));
    }

    @PostMapping("/testAttach")
    public String testAttach(@RequestPart("photo") MultipartFile photo,HttpServletRequest request) throws IOException {
        System.out.println("姓名:"+request.getParameter("username"));
        System.out.println("生日:"+request.getParameter("birth"));
        System.out.println("性别:"+request.getParameter("sex"));
        String originalFileName=photo.getOriginalFilename();
        String type= extName(originalFileName);
        File dest = new File(uploadPath+System.currentTimeMillis()+"."+type);
        photo.transferTo(dest);
        return JSON.toJSONString(new Result().setCode(200).setMessage("图片上传成功"));
    }

}